package org.fearsomej.list.server;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.fearsomej.list.client.service.TaskService;
import org.fearsomej.list.domain.FearsomeCalendarEntry;
import org.fearsomej.list.domain.DataUser;
import org.fearsomej.list.domain.Task;
import org.fearsomej.list.domain.TaskSize;
import org.fearsomej.list.dto.TaskDTO;
import org.fearsomej.list.server.data.EMF;
import org.fearsomej.list.service.GoogleCalendar;

import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.gdata.client.http.AuthSubUtil;
import com.google.gdata.util.AuthenticationException;
import com.google.gdata.util.ServiceException;

public class TaskServiceImpl extends GWTServiceImpl implements TaskService {

	@Override
	public void createTask(TaskDTO task) {
		Task taskDb = new Task();
		DataUser user = getDataUser();
		taskDb.addUser(user);
		taskDb.setSize(TaskSize.valueOf(task.getSize()));
		if (task.isCalendarEntry()) {
			FearsomeCalendarEntry entry = null;
			try {
				entry = createCalendarEntry(taskDb, user);
				if (entry == null)
					return;
			} catch (AuthenticationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (GeneralSecurityException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ServiceException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			taskDb.setCalendarEntry(entry);
		}
		persistEntity(taskDb);
	}

	@Override
	public void authenticate(String token) {
//		UserService userService = UserServiceFactory.getUserService();
//		User user = userService.getCurrentUser();
//		if (user == null) {
//			String thisUrl = getThreadLocalRequest().getRequestURI();
//			try {
//				getThreadLocalResponse().sendRedirect(
//						userService.createLoginURL(thisUrl));
//			} catch (IOException e) {
//				e.printStackTrace();
//				throw new RuntimeException(e);
//			}
//		} else {
//
//			DataUser dataUser = getDataUser();
//
//			FearsomeCalendarEntry returnEntry = null;
//			if (dataUser.getCalendarSessionToken() == null) {
//				String onetimeUseToken = null;
//				if (getThreadLocalRequest().getParameter("token") != null) {
//					onetimeUseToken = AuthSubUtil
//							.getTokenFromReply(getThreadLocalRequest()
//									.getQueryString());
//				}
//				if (onetimeUseToken == null) {
//					String requestUrl = AuthSubUtil.getRequestUrl(
//							getThreadLocalRequest().getRequestURI(),
//							"http://www.google.com/calendar/feeds/", false,
//							true);
//					try {
//						getThreadLocalResponse().sendRedirect(requestUrl);
//					} catch (IOException e) {
//						// TODO Auto-generated catch block
//						e.printStackTrace();
//					}
//					return;
//				} else {
//					String sessionToken = null;
//					try {
//						sessionToken = AuthSubUtil.exchangeForSessionToken(
//								onetimeUseToken, null);
//						dataUser.setCalendarSessionToken(sessionToken);
//						persistEntity(dataUser);
//					} catch (AuthenticationException e) {
//						// TODO Auto-generated catch block
//						e.printStackTrace();
//					} catch (IOException e) {
//						// TODO Auto-generated catch block
//						e.printStackTrace();
//					} catch (GeneralSecurityException e) {
//						// TODO Auto-generated catch block
//						e.printStackTrace();
//					}
//					
//				}
//			}
//		}
	}

	@Override
	public List<TaskDTO> getTasks() {
		EntityManager em = EMF.get().createEntityManager();
		List<TaskDTO> tasks = new ArrayList<TaskDTO>();
		try {
			Query query = em.createQuery("select t from Task t");
			List<Task> taskDbs = (List<Task>) query.getResultList();
			for (Task taskDb : taskDbs) {
				TaskDTO task = new TaskDTO();
				task.setSize(taskDb.getSize().toString());
				tasks.add(task);
			}
		} finally {
			em.close();
		}
		return tasks;
	}
}
